#include "stdafx.h"
#include "LBCPluginMgrImpl.h"

I_LBCPluginFactory::~I_LBCPluginFactory() {}
I_LBCPluginMgr::~I_LBCPluginMgr() {}

int LBCPluginMgrImpl::QueryInterface( REFIID riid, void** pp )
{
	if (NULL==pp)
		return SD_PLUGIN_RET_ERR;

	MAP_RIID_ITEM::iterator it = m_mapRiidItem.find(riid);
	if (it == m_mapRiidItem.end())
		return SD_PLUGIN_RET_ERR;

	_INNTERITEM& item = it->second;
	return item.pFactory->QueryInterface(riid, pp);
}

int LBCPluginMgrImpl::QueryInterface( DWORD dwClassID, void** pp )
{
	if (NULL==pp)
		return SD_PLUGIN_RET_ERR;
	
	MAP_CLASS_RIID::iterator it = m_mapClassRiid.find(dwClassID);
	if (it == m_mapClassRiid.end())
		return SD_PLUGIN_RET_ERR;

	REFIID riid = *it->second.begin();
	return QueryInterface(riid, pp);
}

int LBCPluginMgrImpl::QueryClass( REFIID riid, PDWORD pdwClassID )
{
	if (NULL==pdwClassID)
		return SD_PLUGIN_RET_ERR;
	
	MAP_RIID_ITEM::iterator it = m_mapRiidItem.find(riid);
	if (it == m_mapRiidItem.end())
		return SD_PLUGIN_RET_ERR;
	
	*pdwClassID = it->second.dwClassID;
	return SD_PLUGIN_RET_SUC;
}

int LBCPluginMgrImpl::QueryRiids( DWORD dwClassID, IID* pArr, PDWORD pdwCount )
{
	if (NULL==pdwCount)
		return SD_PLUGIN_RET_ERR;
	
	MAP_CLASS_RIID::iterator it = m_mapClassRiid.find(dwClassID);
	if (it == m_mapClassRiid.end())
		return SD_PLUGIN_RET_ERR;

	DEQ_RIID& item = it->second;
	if (0==*pdwCount)
	{
		*pdwCount = item.size();
		return SD_PLUGIN_RET_SUC;
	}

	if (NULL==pArr)
		return SD_PLUGIN_RET_ERR;

	if (*pdwCount > item.size())
		*pdwCount = item.size();

	DEQ_RIID::iterator itRiid = item.begin();
	for (UINT i = 0; i < *pdwCount; i++, itRiid++)
	{
		pArr[i] = *itRiid;
	}
	
	return SD_PLUGIN_RET_SUC;
}

int LBCPluginMgrImpl::RegisterFactory( DWORD dwClassID, REFIID riid, I_LBCPluginFactory* pFactory )
{
	if (NULL==pFactory)
		return SD_PLUGIN_RET_ERR;

	{
		MAP_RIID_ITEM::iterator it = m_mapRiidItem.find(riid);
		if (it == m_mapRiidItem.end())
		{
			_INNTERITEM item = {0};
			item.dwClassID = dwClassID;
			item.riid = riid;
			item.pFactory = pFactory;
			
			m_mapRiidItem.insert(MAP_RIID_ITEM::value_type(riid, item));
		}
		else
		{
			return SD_PLUGIN_RET_ERR;
		}
	}
	{
		MAP_CLASS_RIID::iterator it = m_mapClassRiid.find(dwClassID);
		if (it == m_mapClassRiid.end())
		{
			DEQ_RIID deq;
			deq.push_back(riid);
			
			m_mapClassRiid.insert(MAP_CLASS_RIID::value_type(dwClassID, deq));
		}
		else
		{
			it->second.push_back(riid);
		}
	}

	return SD_PLUGIN_RET_SUC;
}

void LBCPluginMgrImpl::Destroy()
{
	delete this;
}

LBCPluginMgrImpl::~LBCPluginMgrImpl()
{
	MAP_RIID_ITEM::iterator it = m_mapRiidItem.begin();
	for (; it != m_mapRiidItem.end(); it++)
	{
		it->second.pFactory->Destroy();
	}
}

BOOL CreatePluginManager(I_LBCPluginMgr** pp)
{
	if (NULL==pp)
		return FALSE;

	*pp = new LBCPluginMgrImpl;
	return TRUE;
}